﻿using System;
using System.Configuration;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
using Kangaroo.Configuration;
using Kangaroo.Controls;
using Kangaroo.DAL;
using Kangaroo.Model;
using Kangaroo.Shell.Utils;

namespace Kangaroo.Shell
{
    public partial class Main : Form
    {
        private const string MapViewName = "Map";
        private const string ChartViewName = "Chart";

        private readonly EventViewManager _eventViewManager;
        private readonly ViewManager _viewManager;
        private readonly DiskSpaceMonitor _diskSpaceMonitor;

        private Utils.CheckButtonGroup _checkButtonGroup1;
        private Utils.CheckButtonGroup _checkButtonGroup2;
        private PDGisDriver.PDCPThread _PDCPThread = null;

        public Main()
        {
            try
            {
                InitializeComponent();

                this.WindowState = FormWindowState.Maximized;

                InitializeChartControls();

                if (ConfigurationManager.AppSettings["Encrypt"] == "true")
                {
                    Config.LoadWithDecrypt(ConfigurationManager.AppSettings["ConfigFile"]);
                }
                else
                {
                    Config.Load(ConfigurationManager.AppSettings["ConfigFile"]);
                }

                Text = Config.Instance.WindowTitle;

                refreshTimer.Interval = Config.Instance.Data.UpdateIntervalInSeconds * 1000;

                //            refreshTimer.Start();

                //            RefreshData();
                _checkButtonGroup1 = new Utils.CheckButtonGroup();
                _checkButtonGroup1.Add(mapToolStripButton, mapToolStripMenuItem);
                _checkButtonGroup1.Add(deviceToolStripButton, deviceToolStripMenuItem);
                _checkButtonGroup1.Add(equipToolStripButton, equipToolStripMenuItem);

                _checkButtonGroup2 = new Utils.CheckButtonGroup();
                _checkButtonGroup2.Add(characteristicStripButton, characteristicToolStripMenuItem);
                _checkButtonGroup2.Add(historyStripButton, historyToolStripMenuItem);

                EventHandler toChartView = (o, args) =>
                {
                    if (!(_viewManager.CurrentView is ChartView))
                    {
                        _viewManager.ChangeView(ChartViewName);
                    }
                };
                equipToolStripButton.Click += toChartView;
                deviceToolStripButton.Click += toChartView;

                _eventViewManager = new EventViewManager(eventList);
                _viewManager = new ViewManager((viewName) =>
                {
                    switch (viewName)
                    {
                        case MapViewName:
                            return new MapView(this);
                        case ChartViewName:
                            return new ChartView(this);
                        default:
                            throw new ArgumentException(string.Format("Unexpected view name {0}.", viewName), "viewName");
                    }
                });

                _diskSpaceMonitor = new DiskSpaceMonitor(
                    Config.Instance.MonitorVolumeSpaceQuota * 1024 * 1024,
                    Config.Instance.MonitorVolumes.ToCharArray());
                _diskSpaceMonitor.DiskSpaceAlert += new EventHandler<EventArgs<char[]>>(_diskSpaceMonitor_DiskSpaceAlert);
                _diskSpaceMonitor.DiskSpaceGood += new EventHandler<EventArgs>(_diskSpaceMonitor_DiskSpaceGood);
            }
            catch (Exception ex)
            {
                UIFailureHandler(ex);
            }
        }

        void _diskSpaceMonitor_DiskSpaceGood(object sender, EventArgs e)
        {
            try
            {

                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(delegate
                        {
                            _diskSpaceMonitor_DiskSpaceGood(sender, e);
                        }));
                }
                else
                {
                    if (!diskSpaceToolStripStatusLabel.IsDisposed)
                    {
                        diskSpaceToolStripStatusLabel.Text = Resource.Main__diskSpaceMonitor_DiskSpaceGood_StatusText;
                    }
                }
            }
            catch (Exception ex)
            {
                UIFailureHandler(ex);
            }
        }

        void _diskSpaceMonitor_DiskSpaceAlert(object sender, EventArgs<char[]> e)
        {
            try
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        _diskSpaceMonitor_DiskSpaceAlert(sender, e);
                    }));
                }
                else
                {
                    if (!diskSpaceToolStripStatusLabel.IsDisposed)
                    {

                        string message = string.Format(
                            Resource.Main__diskSpaceMonitor_DiskSpaceAlert_Status_Text,
                            string.Join(", ", e.Data.Select(c => c.ToString(CultureInfo.InvariantCulture)).ToArray()));
                        diskSpaceToolStripStatusLabel.Text = message;
                        UIFailureHandler(message, "", false);
                    }

                }
            }
            catch (Exception ex)
            {
                UIFailureHandler(ex);
            }
            
        }

        public Action<Exception> DataErrorHandler
        {
            get { return exception => BeginInvoke((Action)(() => UIFailureHandler(exception))); }
        }        

        private void refreshTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                _viewManager.CurrentView.Refresh();
            }
            catch (Exception ex)
            {
                UIFailureHandler(ex);
            }
        }

        private void mapToolStripButton_Click(object sender, EventArgs e)
        {
            try
            {
                _viewManager.ChangeView(MapViewName);
            }
            catch (Exception ex)
            {
                UIFailureHandler(ex);
            }
        }

        private void refreshToolStripButton_Click(object sender, EventArgs e)
        {
            try
            {
                _viewManager.CurrentView.Refresh();
            }
            catch (Exception ex)
            {
                UIFailureHandler(ex);
            }
        }

        private void Main_Load(object sender, EventArgs e)
        {
            // 默认界面是设备图界面
            mapToolStripButton_Click(null, null);
        }

        private void connectionTestToolStripButton_Click(object sender, EventArgs e)
        {
            MessageBox.Show(TestConnection()
                ? Resource.Main_TestConnection_ConnectionSuccess
                : Resource.Main_TestConnection_ConnectionFail);
        }

        /// <summary>
        /// 测试数据连接
        /// </summary>
        /// <returns></returns>
        private bool TestConnection()
        {
            try
            {
                Data.General.TestConnection();
                OnDataConnectionSuccess();
                return true;
            }
            catch(Exception ex)
            {
                connectionStatusToolStripStatusLabel.Text = Resource.Main_TestConnection_ConnectionFail;
                UIFailureHandler(ex);
                return false;
            }
        }

        private void UIFailureHandler(Exception exception, bool display = false)
        {
            UIFailureHandler(exception.Message,exception.StackTrace, display);
        }

        private void UIFailureHandler(string message, string stacktrace, bool display = false)
        {
            LogWriter.Instance.WriteToLog(message + stacktrace);
            if (display)
            {
                _eventViewManager.RecordEvent(message);
            }
        }

        private void OnDataConnectionSuccess()
        {
            connectionStatusToolStripStatusLabel.Text = Resource.Main_TestConnection_ConnectionSuccess;
        }

        private void dataWindowToolStripButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (deviceTree.SelectedNode == null || deviceTree.SelectedNode.GetFirstLeaf().Tag == null)
                    return;

                var dataWindow = new DataWindow((ChannelInfo)deviceTree.SelectedNode.GetFirstLeaf().Tag);
                dataWindow.ShowDialog();                
            }
            catch (Exception ex)
            {
                UIFailureHandler(ex);
            }
        }

        private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 如果是用户主动关闭窗口，则要求输入密码
            // 否则 （如系统关机、任务管理器）则不弹出密码框
            if(e.CloseReason == CloseReason.UserClosing && CancelClose())
            {
                // 取消关闭
                e.Cancel = true;
            }
        }

        /// <summary>
        /// 判断是否取消关闭
        /// </summary>
        /// <returns></returns>
        private static bool CancelClose()
        {
            return DialogResult.OK !=
                new PasswordMsgBox(Config.Instance.Password).ShowDialog();
        }

        private void Main_FormClosed(object sender, FormClosedEventArgs e)
        {
            _diskSpaceMonitor.Dispose();
        }

        private void startCollectToolStripButton_Click(object sender, EventArgs e)
        {
            try
            {

                if (_PDCPThread == null)
                {
                    _PDCPThread = new PDGisDriver.PDCPThread();
                }

                _PDCPThread.DBConnectionString = Config.Instance.Data.ConnectionString;

                PDGisDriver.Config.Load();


                _PDCPThread.LoadConfig();

                _PDCPThread.OnError += new PDGisDriver.PDCPThread.OnErrorHandler(thread_OnError);

                _PDCPThread.OnFinish += new PDGisDriver.PDCPThread.OnFinishHandler(thread_OnFinish);

                _PDCPThread.Start();

                LogWriter.Instance.WriteToLog( "开始采集...");

                _PDCPThread.Resume();
            }
            catch (Exception ex)
            {
                UIFailureHandler(ex);
            }
        }

        private void stopCollectToolStripButton_Click(object sender, EventArgs e)
        {

        }


        void thread_OnFinish(string ip, int chn)
        {
            try
            {
                LogWriter.Instance.WriteToLog(string.Format("IP: {0}; Channel: {1}; 信息: {2}", ip, chn, "采集结束"));
                _viewManager.CurrentView.Refresh();
            }
            catch (Exception ex)
            {
                UIFailureHandler(ex);
            }
        }

        void thread_OnError(string ip, int chn, Exception err)
        {
            try
            {
                string eventText = string.Format("IP: {0}; Channel: {1}; 错误信息: {2}", ip, chn, err.Message);
                UIFailureHandler(eventText, err.StackTrace);
            }
            catch (Exception ex)
            {
                UIFailureHandler(ex);
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void mapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            mapToolStripButton.PerformClick();
        }

        private void equipToolStripMenuItem_Click(object sender, EventArgs e)
        {
            equipToolStripButton.PerformClick();
        }

        private void deviceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            deviceToolStripButton.PerformClick();
        }

        private void characteristicToolStripMenuItem_Click(object sender, EventArgs e)
        {
            characteristicStripButton.PerformClick();
        }

        private void historyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            historyStripButton.PerformClick();
        }

        private void realtimeDisplayToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (realtimeDisplayToolStripMenuItem.Checked == false)
            {
                realtimeDisplayToolStripMenuItem.Checked = true;
            }
            else
            {
                realtimeDisplayToolStripMenuItem.Checked = false;
            }
        }
    }
}
